const fs = require('fs')
const path = require('path')
const express = require('express')
const bodyParser = require('body-parser')
const request = require('./util/request')
const packageJSON = require('./package.json')
const exec = require('child_process').exec
const cache = require('./util/apicache').middleware
const { cookieToJson } = require('./util/index')
const fileUpload = require('express-fileupload')
const { BzUser, BzVideo, twinkleNote } = require('./db.js')
const requestMoudle = require('request')
const { log } = require('console')
// version check
exec('npm info NeteaseCloudMusicApi version', (err, stdout, stderr) => {
    if (!err) {
        let version = stdout.trim()
        if (packageJSON.version < version) {
            console.log(
                `最新版本: ${version}, 当前版本: ${packageJSON.version}, 请及时更新`,
            )
        }
    }
})

const app = express()

// CORS & Preflight request
app.use((req, res, next) => {
    if (req.path !== '/' && !req.path.includes('.')) {
        res.set({
            'Access-Control-Allow-Credentials': true,
            'Access-Control-Allow-Origin': req.headers.origin || '*',
            'Access-Control-Allow-Headers': 'X-Requested-With,Content-Type',
            'Access-Control-Allow-Methods': 'PUT,POST,GET,DELETE,OPTIONS',
            'Content-Type': 'application/json; charset=utf-8',
        })
    }
    req.method === 'OPTIONS' ? res.status(204).end() : next()
})

// cookie parser
app.use((req, res, next) => {
    req.cookies = {}
        ; (req.headers.cookie || '').split(/\s*;\s*/).forEach((pair) => {
            let crack = pair.indexOf('=')
            if (crack < 1 || crack == pair.length - 1) return
            req.cookies[
                decodeURIComponent(pair.slice(0, crack)).trim()
            ] = decodeURIComponent(pair.slice(crack + 1)).trim()
        })
    next()
})

// body parser
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: false }))

app.use(fileUpload())

// static
app.use(express.static(path.join(__dirname, 'public')))

// cache
app.use(
    cache('2 minutes', (req, res) => {
        if (req.url.indexOf('/postNote') == -1 && req.url.indexOf('/getNote') == -1){
            return res.statusCode === 200
        }
  }),
)
// router
const special = {
    'daily_signin.js': '/daily_signin',
    'fm_trash.js': '/fm_trash',
    'personal_fm.js': '/personal_fm',
}

fs.readdirSync(path.join(__dirname, 'module'))
    .reverse()
    .forEach((file) => {
        if (!file.endsWith('.js')) return
        let route =
            file in special
                ? special[file]
                : '/' + file.replace(/\.js$/i, '').replace(/_/g, '/')
        let question = require(path.join(__dirname, 'module', file))

        app.use(route, (req, res) => {
            if (typeof req.query.cookie === 'string') {
                req.query.cookie = cookieToJson(req.query.cookie)
            }
            let query = Object.assign(
                {},
                { cookie: req.cookies },
                req.query,
                req.body,
                req.files,
            )

            question(query, request)
                .then((answer) => {
                    console.log('[OK]', decodeURIComponent(req.originalUrl))
                    res.append('Set-Cookie', answer.cookie)
                    res.status(answer.status).send(answer.body)
                })
                .catch((answer) => {
                    console.log('[ERR]', decodeURIComponent(req.originalUrl), {
                        status: answer.status,
                        body: answer.body,
                    })
                    if (answer.body.code == '301') answer.body.msg = '需要登录'
                    res.append('Set-Cookie', answer.cookie)
                    res.status(answer.status).send(answer.body)
                })
        })
    })

const port = process.env.PORT || 3001
const host = process.env.HOST || ''

app.server = app.listen(port, host, () => {
    console.log(
        `网易云音乐API接口已启动，服务端:@ http://${host ? host : 'localhost'
        }:${port}`,
    )
})

//添加的
const bilibili_UUID = '326727897' //326727897 94898339 234425957
//bilibili主页视频
{
    let ptah = `https://api.bilibili.com/x/web-interface/dynamic/region?jsonp=jsonp&ps=200&rid=1`
    requestMoudle(ptah, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body)
            body.data.archives.forEach((item) => {
                BzVideo.find({ aid: item.aid }, function (err, data) {
                    if (err) {
                        console.log(err)
                    } else {
                        if (data.length === 0) {
                            var bzVideo = new BzVideo({
                                aid: item.aid /*aid*/,
                                cid: item.cid /*cid*/,
                                bvid: item.bvid /*bvid*/,
                                tname: item.tname /*类型*/,
                                pic: item.pic /*图片*/,
                                title: item.title /*标题*/,
                                desc: item.desc /*描述*/,
                                duration: item.duration /*时长*/,
                                owner: {
                                    mid: item.owner.mid, //up主mid
                                    name: item.owner.name, //up主昵称
                                    face: item.owner.face, //up主头像
                                } /*up主*/,
                                like: item.stat.like /*赞*/,
                                dislike: item.stat.dislike /*踩*/,
                                view: item.stat.view /*播放量*/,
                                share: item.stat.share /*分享*/,
                                favorite: item.stat.favorite /*收藏*/,
                                coin: item.stat.coin /*投币*/,
                            })
                            bzVideo.save(function (err) {
                                if (err) {
                                    res.end('Error')
                                    return next()
                                }
                            })
                            get_BZ_UserInfo(item.owner.mid)
                        }
                    }
                })
            })
        }
    })
}

//bilibili用户信息
get_BZ_UserInfo(bilibili_UUID) //主动存入
function get_BZ_UserInfo(UUID) {
    let ptah = `https://api.bilibili.com/x/space/acc/info?mid=${UUID}&jsonp=jsonp`
    requestMoudle(ptah, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body)
            var bzUser = new BzUser({
                mid: body.data.mid,
                name: body.data.name,
                face: body.data.face,
                level: body.data.level,
                label: body.data.vip.label.text,
            })
            BzUser.find({ mid: body.data.mid }, function (err, data) {
                if (err) {
                    console.log(err)
                } else {
                    if (data.length === 0) {
                        bzUser.save(function (err) {
                            if (err) {
                                console.log('B站用户信息保存失败,mid=', body.data.mid)
                                res.end('Error')
                                return next()
                            }
                        })
                    }
                }
            })
        }
    })
}
//bilibili用户信息
app.get('/bzUserInfo', function (req, res) {
    BzUser.find({ mid: req.query.mid }, function (err, data) {
        if (!err) {
            let resData = {
                code: 200,
                content: data[0],
                msg: '请求成功',
            }
            res.send(resData)
        } else {
            console.log(err)
        }
    })
})

//bilibili主页视频
app.get('/bzVideoInfo', function (req, res) {
    let page = req.query.page ? req.query.page : 0
    BzVideo.find({}, function (err, data) {
        if (!err) {
            let resData = {
                code: 200,
                nowPage: page,
                content: data,
                msg: '请求成功',
            }
            res.send(resData)
        } else {
            console.log(err)
        }
    })
        .skip(page * 10)
        .limit(10)
        .sort({ _id: -1 })
})

//网易云音乐  相当于做一个中间代理，来处理跨域
app.get('/audioSearch', function (req, res) {
    if (!req.query.song) {
        res.send({
            code: -1,
            msg: '参数不能为空',
        })
    }
    let song = req.query.song
    let path = `http://music.163.com/api/search/get?s=${encodeURI(
        song,
    )}&limit=100&type=1&offset=0`
    requestMoudle(path, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body)
            if (body.result.songs && body.result.songs.length > 0) {
                res.send({
                    code: 200,
                    content: body.result.songs,
                    msg: '成功',
                })
            } else {
                res.send({
                    code: -1,
                    content: [],
                    msg: '没有找到',
                })
            }
        }
    })
})
//音乐链接
app.get('/playAudio', function (req, res) {
    if (!req.query.id) {
        res.send({
            code: -1,
            msg: '参数不能为空',
        })
    }
    let id = req.query.id
    let path = `https://v1.hitokoto.cn/nm/url/${id}`
    requestMoudle(path, function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body)
            if (body.data && body.data.length > 0) {
                res.send({
                    code: 200,
                    content: body.data,
                    msg: '成功',
                })
            } else {
                res.send({
                    code: -1,
                    content: [],
                    msg: '没有找到',
                })
            }
        }
    })
})
//提交评论
app.post('/postNote', function (req, res) {
    if (!req.body) {
        res.send({
            code: -1,
            content: [],
            msg: '参数错误',
        })
    }

    let newNote = {
        name: req.body.name, //up主昵称
        mid: req.body.mid, //up主mid
        face: req.body.face, //up主头像
        note: req.body.note, //评论
        noteTime: +new Date(), //评论时间
    }
    twinkleNote.insertMany(newNote).then(result => {
        res.send({
            code: 200,
            msg: '保存成功',
        })
    }).catch(err => {
        res.end(`Error:${err}`)
        return next()
    })
})

//获取评论
app.get('/getNote', function (req, res) {
    let page = req.query.page ? req.query.page : 0
    twinkleNote
        .find({}, function (err, data) {
            if (!err) {
                let resData = {
                    code: 200,
                    nowPage: page,
                    content: data,
                    msg: '请求成功',
                }
                res.send(resData)
            } else {
                console.log(err)
            }
        })
        .skip(page * 10)
        .limit(10)
        .sort({ _id: -1 })
})

//历史上的今天
app.get('/historyToday', function (req, res) {
    let params = req.query
    let path = `http://api.juheapi.com/japi/toh?v=${params.v}&month=${params.month}&day=${params.day}&key=${params.key}`
    requestMoudle(path,function (error, response, body) {
        if (!error && response.statusCode == 200) {
            body = JSON.parse(body)
            res.send({
                code:200,
                msg:"",
                result:body.result,
            })
        }
    })
})

module.exports = app
